home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 March / PCWorld_2001-03_cd.bin / Software / TemaCD / classbuild / ClassBuilder 2.2 PR405 Setup.exe / {app} / Include / CB_UniqueValueTree.h < prev    next >
C/C++ Source or Header  |  2000-04-06  |  20KB  |  632 lines

  1. #ifndef CB_UNIQUEVALUETREE_H
  2. #define CB_UNIQUEVALUETREE_H
  3.  
  4. #include <assert.h>
  5.  
  6. #include "CB_IteratorMulti.h"
  7.  
  8. // defines for include files
  9. #define RELATION_TEMPLATE_UNIQUEVALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  10. private:\
  11.     ClassTo* _first##NameTo;\
  12.     int _count##NameTo;\
  13. \
  14. public:\
  15.     void Add##NameTo(ClassTo* item)\
  16.     {\
  17.         METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  18.     }\
  19.     void Remove##NameTo(ClassTo* item)\
  20.     {\
  21.         METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  22.     }\
  23.     void RemoveAll##NameTo()\
  24.     {\
  25.         METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  26.     }\
  27.     void DeleteAll##NameTo()\
  28.     {\
  29.         METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  30.     }\
  31.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  32.     {\
  33.         METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  34.     }\
  35.     ClassTo* GetFirst##NameTo() const\
  36.     {\
  37.         METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  38.     }\
  39.     ClassTo* GetLast##NameTo() const\
  40.     {\
  41.         METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  42.     }\
  43.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  44.     {\
  45.         METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  46.     }\
  47.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  48.     {\
  49.         METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  50.     }\
  51.     int Get##NameTo##Count() const\
  52.     {\
  53.         METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  54.     }\
  55.     ITERATOR_TEMPLATE_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  56.  
  57. #define RELATION_TEMPLATE_NOFILTER_UNIQUEVALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  58. private:\
  59.     ClassTo* _first##NameTo;\
  60.     int _count##NameTo;\
  61. \
  62. public:\
  63.     void Add##NameTo(ClassTo* item)\
  64.     {\
  65.         METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  66.     }\
  67.     void Remove##NameTo(ClassTo* item)\
  68.     {\
  69.         METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  70.     }\
  71.     void RemoveAll##NameTo()\
  72.     {\
  73.         METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  74.     }\
  75.     void DeleteAll##NameTo()\
  76.     {\
  77.         METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  78.     }\
  79.     void Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  80.     {\
  81.         METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  82.     }\
  83.     ClassTo* GetFirst##NameTo() const\
  84.     {\
  85.         METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  86.     }\
  87.     ClassTo* GetLast##NameTo() const\
  88.     {\
  89.         METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  90.     }\
  91.     ClassTo* GetNext##NameTo(ClassTo* pos) const\
  92.     {\
  93.         METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  94.     }\
  95.     ClassTo* GetPrev##NameTo(ClassTo* pos) const\
  96.     {\
  97.         METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  98.     }\
  99.     int Get##NameTo##Count() const\
  100.     {\
  101.         METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  102.     }\
  103.     ITERATOR_TEMPLATE_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  104.  
  105. #define RELATION_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  106. private:\
  107.     ClassTo* _first##NameTo;\
  108.     int _count##NameTo;\
  109. \
  110. public:\
  111.     void Add##NameTo(ClassTo* item);\
  112.     void Remove##NameTo(ClassTo* item);\
  113.     void RemoveAll##NameTo();\
  114.     void DeleteAll##NameTo();\
  115.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  116.     ClassTo* GetFirst##NameTo() const;\
  117.     ClassTo* GetLast##NameTo() const;\
  118.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  119.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  120.     int Get##NameTo##Count() const;\
  121.     ITERATOR_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  122.  
  123. #define RELATION_NOFILTER_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  124. private:\
  125.     ClassTo* _first##NameTo;\
  126.     int _count##NameTo;\
  127. \
  128. public:\
  129.     void Add##NameTo(ClassTo* item);\
  130.     void Remove##NameTo(ClassTo* item);\
  131.     void RemoveAll##NameTo();\
  132.     void DeleteAll##NameTo();\
  133.     void Replace##NameTo(ClassTo* item, ClassTo* newItem);\
  134.     ClassTo* GetFirst##NameTo() const;\
  135.     ClassTo* GetLast##NameTo() const;\
  136.     ClassTo* GetNext##NameTo(ClassTo* pos) const;\
  137.     ClassTo* GetPrev##NameTo(ClassTo* pos) const;\
  138.     int Get##NameTo##Count() const;\
  139.     ITERATOR_NOFILTER_MULTI_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  140.  
  141. #define RELATION_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  142. public:\
  143.     ClassFrom* _ref##NameFrom;\
  144.     ClassTo* _parent##NameFrom;\
  145.     ClassTo* _left##NameFrom;\
  146.     ClassTo* _right##NameFrom;\
  147. \
  148. public:\
  149.     ClassFrom* Get##NameFrom() const { return _ref##NameFrom; };
  150.  
  151. // defines implementation
  152. #define INIT_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  153.     _first##NameTo = (ClassTo*)0;\
  154.     _count##NameTo = 0;
  155.  
  156. #define EXIT_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  157.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  158.           Remove##NameTo(item); }
  159.  
  160. #define REPLACE_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  161.     _first##NameTo = pOld->_first##NameTo;\
  162.     _count##NameTo = pOld->_count##NameTo;\
  163.     pOld->_first##NameTo = (ClassTo*)0;\
  164.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  165.           item->_ref##NameFrom = this; }
  166.  
  167. #define INIT_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  168.     _ref##NameFrom = (ClassFrom*)0;\
  169.     _parent##NameFrom = (ClassTo*)0;\
  170.     _left##NameFrom = (ClassTo*)0;\
  171.     _right##NameFrom = (ClassTo*)0;
  172.  
  173. #define EXIT_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  174.     if (_ref##NameFrom)\
  175.         _ref##NameFrom->Remove##NameTo(this);
  176.  
  177. #define REPLACE_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  178.     _ref##NameFrom = (ClassFrom*)0;\
  179.     _parent##NameFrom = (ClassTo*)0;\
  180.     _left##NameFrom = (ClassTo*)0;\
  181.     _right##NameFrom = (ClassTo*)0;\
  182.     if (pOld->_ref##NameFrom)\
  183.         pOld->_ref##NameFrom->Replace##NameTo(pOld, this);
  184.  
  185. #define REMOVE_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  186.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  187.       {\
  188.           (void)new UndoSubChange(item);\
  189.           Remove##NameTo(item);\
  190.       } }
  191.  
  192. #define SAVE_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  193.     p##ClassTo->_ref##NameFrom = _ref##NameFrom;
  194.  
  195. #define RESTORE_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  196.     {\
  197.         ClassFrom* p##ClassFrom = p##ClassTo->_ref##NameFrom;\
  198.         _ref##NameFrom = 0;\
  199.         p##ClassFrom->Add##NameTo(this);\
  200.     }\
  201.  
  202. #define REMOVE_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  203.     if (_ref##NameFrom)\
  204.     {\
  205.         ClassFrom* p##ClassFrom = _ref##NameFrom;\
  206.         _ref##NameFrom->Remove##NameTo(this);\
  207.         _ref##NameFrom = p##ClassFrom;\
  208.     }
  209.  
  210. #define CLEANUP_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  211.     _ref##NameFrom = (ClassFrom*)0;\
  212.     _parent##NameFrom = (ClassTo*)0;\
  213.     _left##NameFrom = (ClassTo*)0;\
  214.     _right##NameFrom = (ClassTo*)0;
  215.  
  216. #define METHODS_UNIQUEVALUETREE_ACTIVE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  217. void ClassFrom##::Add##NameTo(ClassTo* item)\
  218. {\
  219.     METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  220. }\
  221. \
  222. void ClassFrom##::Remove##NameTo(ClassTo* item)\
  223. {\
  224.     METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  225. }\
  226. \
  227. void ClassFrom##::RemoveAll##NameTo()\
  228. {\
  229.     METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  230. }\
  231. \
  232. void ClassFrom##::DeleteAll##NameTo()\
  233. {\
  234.     METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  235. }\
  236. \
  237. void ClassFrom##::Replace##NameTo(ClassTo* item, ClassTo* newItem)\
  238. {\
  239.     METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  240. }\
  241. \
  242. ClassTo* ClassFrom##::GetFirst##NameTo() const\
  243. {\
  244.     METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  245. }\
  246. \
  247. ClassTo* ClassFrom##::GetLast##NameTo() const\
  248. {\
  249.     METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  250. }\
  251. \
  252. ClassTo* ClassFrom##::GetNext##NameTo(ClassTo* pos) const\
  253. {\
  254.     METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  255. }\
  256. \
  257. ClassTo* ClassFrom##::GetPrev##NameTo(ClassTo* pos) const\
  258. {\
  259.     METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  260. }\
  261. \
  262. int ClassFrom##::Get##NameTo##Count() const\
  263. {\
  264.     METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  265. }
  266.  
  267. #define METHOD_UNIQUEVALUETREE_ADD(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  268.     assert(this);\
  269. \
  270.     assert(item);\
  271.     assert(item->_ref##NameFrom == (ClassFrom*)0);\
  272. \
  273.     _count##NameTo++;\
  274. \
  275.     item->_ref##NameFrom = this;\
  276. \
  277.     if (_first##NameTo)\
  278.     {\
  279.         ClassTo* current = _first##NameTo;\
  280.         unsigned long bit = 0x1;\
  281.         while (1)\
  282.         {\
  283.             assert(current->member != item->member);\
  284. \
  285.             if ((current->member & bit) == (item->member & bit))\
  286.             {\
  287.                 if (current->_left##NameFrom)\
  288.                 {\
  289.                     current = current->_left##NameFrom;\
  290.                 }\
  291.                 else\
  292.                 {\
  293.                     current->_left##NameFrom = item;\
  294.                     item->_parent##NameFrom = current;\
  295.                     break;\
  296.                 }\
  297.             }\
  298.             else\
  299.             {\
  300.                 if (current->_right##NameFrom)\
  301.                 {\
  302.                     current = current->_right##NameFrom;\
  303.                 }\
  304.                 else\
  305.                 {\
  306.                     current->_right##NameFrom = item;\
  307.                     item->_parent##NameFrom = current;\
  308.                     break;\
  309.                 }\
  310.             }\
  311. \
  312.             bit <<= 1;\
  313.         }\
  314.     }\
  315.     else\
  316.     {\
  317.         _first##NameTo = item;\
  318.     }
  319.  
  320. #define METHOD_UNIQUEVALUETREE_REMOVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  321.     assert(this);\
  322. \
  323.     assert(item);\
  324.     assert(item->_ref##NameFrom == this);\
  325. \
  326.     ClassFrom##::##NameTo##Iterator::Check(item);\
  327. \
  328.     _count##NameTo--;\
  329. \
  330.     ClassTo* replacement = 0;\
  331.     ClassTo* move = 0;\
  332.     if (item->_left##NameFrom)\
  333.     {\
  334.         replacement = item->_left##NameFrom;\
  335.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  336.         move = item->_right##NameFrom;\
  337.     }\
  338.     else if (item->_right##NameFrom)\
  339.     {\
  340.         replacement = item->_right##NameFrom;\
  341.         replacement->_parent##NameFrom = item->_parent##NameFrom;\
  342.     }\
  343. \
  344.     ClassTo* parent = item->_parent##NameFrom;\
  345.     if (parent)\
  346.     {\
  347.         if (parent->_left##NameFrom == item)\
  348.         {\
  349.             parent->_left##NameFrom = replacement;\
  350.         }\
  351.         else\
  352.         {\
  353.             parent->_right##NameFrom = replacement;\
  354.         }\
  355.     }\
  356.     else\
  357.     {\
  358.         _first##NameTo = replacement;\
  359.     }\
  360. \
  361.     if (replacement)\
  362.     {\
  363.         while (1)\
  364.         {\
  365.             ClassTo* tmp = replacement->_right##NameFrom;\
  366.             replacement->_right##NameFrom = move;\
  367.             if (move)\
  368.             {\
  369.                 move->_parent##NameFrom = replacement;\
  370.             }\
  371.             \
  372.             if (!replacement->_left##NameFrom)\
  373.             {\
  374.                 if (tmp)\
  375.                 {\
  376.                     replacement->_left##NameFrom = tmp;\
  377.                     tmp = 0;\
  378.                 }\
  379.                 else\
  380.                 {\
  381.                     break;\
  382.                 }\
  383.             }\
  384.             move = tmp;\
  385.             replacement = replacement->_left##NameFrom;\
  386.         }\
  387.     }\
  388. \
  389.     item->_ref##NameFrom = (ClassFrom*)0;\
  390.     item->_parent##NameFrom = (ClassTo*)0;\
  391.     item->_left##NameFrom = (ClassTo*)0;\
  392.     item->_right##NameFrom = (ClassTo*)0;
  393.  
  394. #define METHOD_UNIQUEVALUETREE_REMOVEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  395.     assert(this);\
  396. \
  397.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  398.           Remove##NameTo(item);
  399.  
  400. #define METHOD_UNIQUEVALUETREE_DELETEALL(ClassFrom, NameFrom, ClassTo, NameTo) \
  401.     assert(this);\
  402. \
  403.     for (ClassTo* item = GetFirst##NameTo(); item; item = GetFirst##NameTo())\
  404.           delete item;
  405.  
  406. #define METHOD_UNIQUEVALUETREE_REPLACE(member, ClassFrom, NameFrom, ClassTo, NameTo) \
  407.     assert(this);\
  408. \
  409.     assert(item);\
  410.     assert(item->_ref##NameFrom == this);\
  411. \
  412.     assert(newItem);\
  413.     assert(newItem->_ref##NameFrom == (ClassFrom*)0);\
  414. \
  415.     if (item->member == newItem->member)\
  416.     {\
  417.         ClassFrom##::##NameTo##Iterator::Check(item, newItem);\
  418.         if (_first##NameTo == item)\
  419.         {\
  420.             _first##NameTo = newItem;\
  421.         }\
  422.         if (item->_parent##NameFrom)\
  423.         {\
  424.             if (item->_parent##NameFrom->_left##NameFrom == item)\
  425.             {\
  426.                 item->_parent##NameFrom->_left##NameFrom = newItem;\
  427.             }\
  428.             else if (item->_parent##NameFrom->_right##NameFrom == item)\
  429.             {\
  430.                 item->_parent##NameFrom->_right##NameFrom = newItem;\
  431.             }\
  432.         }\
  433.         newItem->_ref##NameFrom = this;\
  434.         newItem->_parent##NameFrom = item->_parent##NameFrom;\
  435.         newItem->_left##NameFrom = item->_left##NameFrom;\
  436.         newItem->_right##NameFrom = item->_right##NameFrom;\
  437.         item->_ref##NameFrom = (ClassFrom*)0;\
  438.         item->_parent##NameFrom = (ClassTo*)0;\
  439.         item->_left##NameFrom = (ClassTo*)0;\
  440.         item->_right##NameFrom = (ClassTo*)0;\
  441.     }\
  442.     else\
  443.     {\
  444.         ClassFrom##::##NameTo##Iterator::Check(item);\
  445.         Remove##NameTo(item);\
  446.         Add##NameTo(newItem);\
  447.     }
  448.  
  449. #define METHOD_UNIQUEVALUETREE_GETFIRST(ClassFrom, NameFrom, ClassTo, NameTo) \
  450.     assert(this);\
  451.     return _first##NameTo;
  452.  
  453. #define METHOD_UNIQUEVALUETREE_GETLAST(ClassFrom, NameFrom, ClassTo, NameTo) \
  454.     assert(this);\
  455. \
  456.     ClassTo* result = _first##NameTo;\
  457.     while (result)\
  458.     {\
  459.         while (result->_right##NameFrom)\
  460.         {\
  461.             result = result->_right##NameFrom;\
  462.         }\
  463. \
  464.         if (result->_left##NameFrom)\
  465.         {\
  466.             result = result->_left##NameFrom;\
  467.         }\
  468.         else\
  469.         {\
  470.             break;\
  471.         }\
  472.     }\
  473. \
  474.     return result;
  475.  
  476. #define METHOD_UNIQUEVALUETREE_GETNEXT(ClassFrom, NameFrom, ClassTo, NameTo) \
  477.     assert(this);\
  478. \
  479.     ClassTo* result = 0;\
  480.     if (pos == (ClassTo*)0)\
  481.         result = _first##NameTo;\
  482.     else\
  483.     {\
  484.         assert(pos->_ref##NameFrom == this);\
  485. \
  486.         if (pos->_left##NameFrom)\
  487.         {\
  488.             result = pos->_left##NameFrom;\
  489.         }\
  490.         else\
  491.         {\
  492.             if (pos->_right##NameFrom)\
  493.             {\
  494.                 result = pos->_right##NameFrom;\
  495.             }\
  496.             else\
  497.             {\
  498.                 ClassTo* parent = pos->_parent##NameFrom;\
  499.                 while (parent && (parent->_right##NameFrom == 0 || parent->_right##NameFrom == pos))\
  500.                 {\
  501.                     pos = parent;\
  502.                     parent = parent->_parent##NameFrom;\
  503.                 }\
  504. \
  505.                 if (parent)\
  506.                 {\
  507.                     result = parent->_right##NameFrom;\
  508.                 }\
  509.             }\
  510.         }\
  511.     }\
  512. \
  513.     return result;
  514.  
  515. #define METHOD_UNIQUEVALUETREE_GETPREV(ClassFrom, NameFrom, ClassTo, NameTo) \
  516.     assert(this);\
  517. \
  518.     ClassTo* result = 0;\
  519.     if (pos == (ClassTo*)0)\
  520.         result = GetLast##NameTo();\
  521.     else\
  522.     {\
  523.         assert(pos->_ref##NameFrom == this);\
  524. \
  525.         if (pos->_parent##NameFrom)\
  526.         {\
  527.             if (pos->_parent##NameFrom->_left##NameFrom == pos || pos->_parent##NameFrom->_left##NameFrom == 0)\
  528.             {\
  529.                 result = pos->_parent##NameFrom;\
  530.             }\
  531.             else /* Right branche and valid left branche */\
  532.             {\
  533.                 result = pos->_parent##NameFrom->_left##NameFrom;\
  534.                 while (1)\
  535.                 {\
  536.                     while (result->_right##NameFrom)\
  537.                     {\
  538.                         result = result->_right##NameFrom;\
  539.                     }\
  540. \
  541.                     if (result->_left##NameFrom)\
  542.                     {\
  543.                         result = result->_left##NameFrom;\
  544.                     }\
  545.                     else\
  546.                     {\
  547.                         break;\
  548.                     }\
  549.                 }\
  550.             }\
  551.         }\
  552.     }\
  553. \
  554.     return result;
  555.  
  556. #define METHOD_UNIQUEVALUETREE_GETCOUNT(ClassFrom, NameFrom, ClassTo, NameTo) \
  557.     assert(this);\
  558.     return _count##NameTo;
  559.  
  560. #define METHODS_UNIQUEVALUETREE_PASSIVE(ClassFrom, NameFrom, ClassTo, NameTo)
  561.  
  562. #ifndef _BODY_VALUETREE_FIND
  563. #define _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  564.     ClassTo* result = 0;\
  565.     if (_first##NameTo)\
  566.     {\
  567.         ClassTo* item = _first##NameTo;\
  568.         unsigned long bit = 0x1;\
  569.         while (1)\
  570.         {\
  571.             if (item->member == value)\
  572.             {\
  573.                 result = item;\
  574.                 break;\
  575.             }\
  576. \
  577.             if ((item->member & bit) == (value & bit))\
  578.             {\
  579.                 if (item->_left##NameFrom)\
  580.                 {\
  581.                     item = item->_left##NameFrom;\
  582.                 }\
  583.                 else\
  584.                 {\
  585.                     break;\
  586.                 }\
  587.             }\
  588.             else\
  589.             {\
  590.                 if (item->_right##NameFrom)\
  591.                 {\
  592.                     item = item->_right##NameFrom;\
  593.                 }\
  594.                 else\
  595.                 {\
  596.                     break;\
  597.                 }\
  598.             }\
  599. \
  600.             bit <<= 1;\
  601.         }\
  602.     }
  603. #endif
  604.  
  605. #define BODY_UNIQUEVALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  606.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  607.     return result;
  608.  
  609. #define BODY_UNIQUEVALUETREE_FINDREVERSE(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  610.     _BODY_VALUETREE_FIND(member, value, ClassFrom, NameFrom, ClassTo, NameTo) \
  611.     return result;
  612.  
  613. #define WRITE_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  614.     rCArchive << Get##NameTo##Count();\
  615.     { for (ClassTo* item = GetFirst##NameTo(); item; item = GetNext##NameTo(item))\
  616.           rCArchive << item->_index; }
  617.  
  618. #define READ_UNIQUEVALUETREE_ACTIVE(ClassFrom, NameFrom, ClassTo, NameTo) \
  619.     {\
  620.         int count;\
  621.         int index;\
  622. \
  623.         rCArchive >> count;\
  624.         for (int i = 0; i < count; i++)\
  625.         {\
  626.             rCArchive >> index;\
  627.             Add##NameTo((ClassTo*)(pointerArray[index]));\
  628.         }\
  629.     }
  630.  
  631. #endif
  632.